﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using VersionComparer.Images;

namespace VersionComparer.Base
{
    /// <summary>
    /// This class allows calculating variants for the images, to add state icons to the normal icons
    /// </summary>
    public class ImageVariants
    {
        #region inner classes
        /// <summary>
        /// type of positions
        /// </summary>
        [FlagsAttribute]
        public enum ImageVariantPosition
        {
            Left = 0,
            Right = 1,
            Top = 0,
            Bottom = 2,
            TopLeft = Top | Left,
            BottomRight = Bottom | Right,
            TopRight = Top | Right,
            BottomLeft = Bottom | Left
        }
        #endregion inner classes

        #region fields
        /// <summary>
        /// Image position
        /// </summary>
        ImageVariantPosition position;
        /// <summary>
        /// pre-calculated variants for each image
        /// </summary>
        private Dictionary<Image, Dictionary<int, Image>> variants = new Dictionary<Image, Dictionary<int, Image>>();
        /// <summary>
        /// list with all the variants for direct access
        /// </summary>
        private List<Image> variantImages = new List<Image>();
        #endregion fields

        #region constructors
        public ImageVariants()
        {
        }
        #endregion constructors
        
        #region properties
        /// <summary>
        /// Images sizes
        /// </summary>
        protected virtual Size Size
        {
            get
            {
                return new Size(16, 16);
            }
        }
        /// <summary>
        /// Transparent color
        /// </summary>
        protected virtual Color TransparentImage
        {
            get
            {
                return Color.FromArgb ( 255,254,254,254 );
            }
        }
        /// <summary>
        /// Image position
        /// </summary>
        protected virtual ImageVariantPosition Position
        {
            get
            {
                return position;
            }
            set
            {
                position = value;
            }
        }
        #endregion properties


        /// <summary>
        /// Initializes the object
        /// </summary>
        /// <param name="position"></param>
        /// <param name="variants"></param>
        public void Initialize(ImageVariantPosition position, params Image[] variants)
        {
            this.position = position;
            variantImages = new List<Image>(variants);
            Color transparentImage = TransparentImage;
            /*
            if (transparentImage != Color.Empty)
            {
                foreach (var image in variantImages)
                {
                    Bitmap bmp = image as Bitmap;
                    if (bmp != null)
                        bmp.MakeTransparent(transparentImage);
                }
            }
             * */
        }
        /// <summary>
        /// Returns a pre calculated variant given its id
        /// </summary>
        /// <param name="variant"></param>
        /// <returns></returns>
        protected virtual Image GetVariantModifier ( int variant )
        {
            return variantImages[variant - 1];
        }

        /// <summary>
        /// Returns an image variant
        /// </summary>
        /// <param name="image">original image</param>
        /// <param name="variant">variant</param>
        /// <returns>variant image</returns>
        public virtual Image GetImageVariant ( Image image , int variant )
        {
            if (image == null)
                return null;
            if (variant == 0)
                return image;
            Image result;
            Dictionary<int, Image> imageVariants;
            lock (variants)
            {
                if (!variants.TryGetValue(image, out imageVariants))
                {
                    imageVariants = new Dictionary<int, Image>();
                    imageVariants.Add(0, image);
                    variants.Add(image, imageVariants);
                }
            }
            lock (imageVariants)
            {
                if (!imageVariants.TryGetValue(variant, out result))
                {
                    result = new Bitmap(image, Size);
                    var imageModifier= GetVariantModifier ( variant );
                    Point pos = new Point();
                    if (imageModifier != null)
                    {
                        if ((Position & ImageVariantPosition.Right) == ImageVariantPosition.Right)
                            pos.X = result.Width - imageModifier.Width;

                        if ((Position & ImageVariantPosition.Bottom) == ImageVariantPosition.Bottom)
                            pos.Y = result.Height - imageModifier.Height;
                        using ( var graphics = Graphics.FromImage ( result ))
                            graphics.DrawImage(imageModifier, pos);
                    }
                    imageVariants.Add(variant, result);
                }
            }
            return result;
        }
    }
}
